package com.topscomm.appv2.mq;
import java.util.List;
import java.util.Map;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.IBasicService;
import com.topscomm.basic.util.Config;
import com.topscomm.cbo.CboSystemConst.CboTableLogOperateTypeEnum;
import com.topscomm.cbo.pojo.CboDeptEntity;
import com.topscomm.cbo.pojo.CboSystemErrorLogEntity;
import com.topscomm.cbo.pojo.CboOrgEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboSystemErrorLogService;
import com.topscomm.cbo.service.impl.CboDeptService;
import com.topscomm.cbo.service.impl.CboOrgService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringUtil;

/**
 * 用于同步基础信息的mq（消费者）
 *
 * @author 王兴华
 *
 */
@Component
@RabbitListener(queues = "topscomm.mpsc.basicData.sync")
public class AppBasicHandler {
	/**
	 * 处理CboUser,CboDept,MisEmployee表的数据 createby张龙飞 modifiyby王兴华
	 */
	@RabbitHandler
	public void process(String hello, Channel channel, Message message) throws Exception {
		if ("false".equals(Config.getInstance().getValue("mq.basicData.sync.receive", "false"))) {
			channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
			return;
		}
		String json = "";
		try {
			json = new String(message.getBody(), "utf-8");
			handlerData(json);
			//手动应答，可删除消息
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		}
		catch(TapUserException ue)
		{
            //重新放到队列 解决消费时间顺序混乱问题
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,true);
		} catch (Exception e) {
			writeError(e, json, message);
			// 拒绝消息
			channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
			//ErrorUtil.writeLog(e);
		}
	}

	public static void handlerData(String json) throws Exception {
		Map<String, Object> transData = JSONObject.parseObject(json, Map.class);
		String table = transData.get("category").toString();
		String action = transData.get("action").toString();
		List<Map> list = (List<Map>) transData.get("data");
		String primaryKey = "code", packageName = "com.topscomm.cbo.pojo.";
		if ("MisEmployee".equals(table)) {
			primaryKey = "usercode";
			packageName = "com.topscomm.mis.pojo.";
			return;
		}
		IBasicService service = (IBasicService) SpringUtil.getBean(StringUtil.lowerFirst(table) + "Service");
		CboDeptService deptService = (CboDeptService) SpringUtil.getBean("cboDeptService");
		CboOrgService orgService = (CboOrgService) SpringUtil.getBean("cboOrgService");
		CboUserService userService = (CboUserService) SpringUtil.getBean("cboUserService");
		int count = 0;
		for (Map map : list) {
			if (!map.containsKey(primaryKey) || map.get(primaryKey) == null)
				continue;
			String whereSql = primaryKey + "='" + map.get(primaryKey) + "'";
			if (CboTableLogOperateTypeEnum.Delete.equals(action)) {
				service.deleteByWhere(whereSql);
			} else if (CboTableLogOperateTypeEnum.Insert.equals(action)
					|| CboTableLogOperateTypeEnum.Update.equals(action)) {

				switchData(map, table, deptService, orgService, userService);

				count = service.getCount(whereSql);
				if (count > 0) {
					service.updateByWhere(map, whereSql);
				} else {
					Class<BasicEntity> entityClass = (Class<BasicEntity>) Class.forName(packageName + table + "Entity");
					BasicEntity entity = (BasicEntity) entityClass.newInstance();
					entity.convertFromMap(map);
					service.insert(entity);
				}
			}
		}
	}

	private static void writeError(Exception e, String json, Message message) {
		CboSystemErrorLogEntity logEntity = new CboSystemErrorLogEntity();
		logEntity.setDisplayerror("接收mq失败");
		logEntity.setDescription(json);
		logEntity.setEnabled(1);
		logEntity.setReason(e.getMessage());
		logEntity.setSource("[mq]" + message.getMessageProperties().getConsumerQueue());
		ICboSystemErrorLogService errorLogService = (ICboSystemErrorLogService) SpringUtil.getBean("cboSystemErrorLogService");
		errorLogService.insert(logEntity);
	}

	/**
	 *
	 * @author zhanglongfei
	 * @date 2019年7月4日
	 * @description 处理数据，主要是把code转id
	 */
	private static void switchData(Map map, String table, CboDeptService deptService, CboOrgService orgService,
			CboUserService userService) {
		map.remove("id");
		map.remove("adminlevel");
		// map.remove("createorgid");
		// map.remove("createon");
		// map.remove("createuser");
		// map.remove("modifiedon");
		// map.remove("modifieduser");
		if (table.equals(CboUserEntity.tableName)) {
			if (map.containsKey("orgcode") && map.get("orgcode") != null
					&& !StringUtil.isEmpty(map.get("orgcode").toString())) {
				CboOrgEntity orgEntity = orgService.queryObjectByWhere("code ='" + map.get("orgcode").toString() + "'");
				if (orgEntity != null) {
					map.put("orgid", orgEntity.getId());
				}
			}
			if (map.containsKey("deptcode") && map.get("deptcode") != null
					&& !StringUtil.isEmpty(map.get("deptcode").toString())) {
				CboDeptEntity deptEntity = deptService
						.queryObjectByWhere("code ='" + map.get("deptcode").toString() + "'");
				if (deptEntity != null) {
					map.put("deptid", deptEntity.getId());
				}else
				    throw new TapUserException("没有找到部门");
			}
			if (map.containsKey("workorgcode") && map.get("workorgcode") != null
					&& !StringUtil.isEmpty(map.get("workorgcode").toString())) {
				CboOrgEntity orgEntity = orgService
						.queryObjectByWhere("code ='" + map.get("workorgcode").toString() + "'");
				if (orgEntity != null) {
					map.put("workorgid", orgEntity.getId());
				}
			}
			if (map.containsKey("workdeptcode") && map.get("workdeptcode") != null
					&& !StringUtil.isEmpty(map.get("workdeptcode").toString())) {
				CboDeptEntity deptEntity = deptService
						.queryObjectByWhere("code ='" + map.get("workdeptcode").toString() + "'");
				if (deptEntity != null) {
					map.put("workdeptid", deptEntity.getId());
				}
			}
		} else if (table.equals(CboDeptEntity.tableName)) {
			if (map.containsKey("parentcode") && map.get("parentcode") != null
					&& !StringUtil.isEmpty(map.get("parentcode").toString())) {
				CboDeptEntity deptEntity = deptService
						.queryObjectByWhere("code ='" + map.get("parentcode").toString() + "'");
				if (deptEntity != null) {
					map.put("parentid", deptEntity.getId());
				}
				else
				    throw new TapUserException("没有找到父部门");
			}
			if (map.containsKey("orgcode") && map.get("orgcode") != null
					&& !StringUtil.isEmpty(map.get("orgcode").toString())) {
				CboOrgEntity orgEntity = orgService.queryObjectByWhere("code ='" + map.get("orgcode").toString() + "'");
				if (orgEntity != null) {
					map.put("orgid", orgEntity.getId());
				}
			}
			if (map.containsKey("headercode") && map.get("headercode") != null
					&& !StringUtil.isEmpty(map.get("headercode").toString())) {
				CboUserEntity userEntity = userService
						.queryObjectByWhere("code ='" + map.get("headercode").toString() + "'");
				if (userEntity != null) {
					map.put("headerids", userEntity.getId());
				}
			}
		}
	}
}
